package com.itheima.sh.esdemo.demo;
import com.alibaba.fastjson.JSON;
import com.itheima.sh.esdemo.pojo.User;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpHost;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.aggregations.metrics.Avg;
import org.elasticsearch.search.aggregations.metrics.AvgAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.util.List;
import java.util.Map;

/**
 * 文档 搜索
 *
 * 高亮搜索
 *
 * @作者 itcast
 * @创建日期 2021/5/12 18:28
 **/
public class EsDemo04 {
    RestHighLevelClient client;
    /**
     * 聚合处理
     * @throws IOException
     */
    @Test
    public void aggregations() throws IOException {
        //1.创建搜索请求
        SearchRequest request = new SearchRequest("user");
        // 1.1  创建请求参数对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        // 构建 聚合条件  AggregationBuilders 快捷的构建聚合参数
        // 2. 构建按照性别分桶的聚合条件
        //          方法名就是聚合类型名称    参数1：自定义的聚合名称   参数2:根据哪个字段
        TermsAggregationBuilder termAgg = AggregationBuilders.terms("terms_by_gender").field("gender");
        // 2. 构建按照年龄求平均值
        AvgAggregationBuilder avgAgg = AggregationBuilders.avg("avg_by_age").field("age");
        // 将求平均年龄设置为分桶条件的子聚合 :  先求分组  分组后再求每个分组的平均年龄
        termAgg.subAggregation(avgAgg);
        builder.aggregation(termAgg);
        request.source(builder);
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 得到聚合结果
        Aggregations aggregations = response.getAggregations();
        // 根据自定义的聚合名称得到指定的聚合结果
        // 什么样的聚合处理 就用什么样的接口去接收
        Terms termResult = aggregations.get("terms_by_gender");
        List<? extends Terms.Bucket> buckets = termResult.getBuckets();
        for (Terms.Bucket bucket : buckets) {
            System.out.println("当前分组的key ===> " + bucket.getKeyAsString());
            System.out.println("当前分组的文档数量 ===> " + bucket.getDocCount());
            // 得到当前分桶下的子聚合处理结果
            Aggregations subAgg = bucket.getAggregations();
            Avg avgResult = subAgg.get("avg_by_age");
            System.out.println("当前分组年龄的平均值 ===> " + avgResult.getValue());
        }
    }

    @Test
    public void hight() throws IOException {
        //1.创建搜索请求
        SearchRequest request = new SearchRequest("user");
        // 1.1  创建请求参数对象
        SearchSourceBuilder builder = new SearchSourceBuilder();
        //   查询条件
        builder.query(QueryBuilders.matchQuery("note","唱歌跳舞javaee"));
        //   高亮条件
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("note");// 高亮的字段
        highlightBuilder.preTags("<span style='color:red'>");
        highlightBuilder.postTags("</span>");
        builder.highlighter(highlightBuilder);
        request.source(builder);
        // 2. 执行搜索
        SearchResponse response = client.search(request, RequestOptions.DEFAULT);
        // 获取总数量
        SearchHits hits = response.getHits();
        System.out.println("查询到的结果总数量: " + hits.getTotalHits().value);
        SearchHit[] docList = hits.getHits();
        for (SearchHit doc : docList) {
            String userJson = doc.getSourceAsString();
            User user = JSON.parseObject(userJson, User.class);
            // 单独的获取高亮处理结果
            // 获取高亮结果
            Map<String, HighlightField> highlightFields = doc.getHighlightFields();
            // 获取note字段的高亮处理结果
            HighlightField highlightField = highlightFields.get("note");
            // 获取高亮处理结果的片段数组
            Text[] fragments = highlightField.getFragments();
            // 将所有片段数组拼接到一起 才是note字段的完整高亮处理结果
            String noteResult = StringUtils.join(fragments);
            // 将高亮处理结果 设置到user的note字段中
            user.setNote(noteResult);
            System.out.println(user);
        }
    }
    @Before
    public void init(){
        client = new RestHighLevelClient(
                RestClient.builder(
                        new HttpHost("192.168.200.130", 9200, "http")));
    }
    @After
    public void close(){
        try {
            client.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
